/**
 * EasyDrag 1.5 - Drag & Drop jQuery Plug-in
 * 
 * Thanks for the community that is helping the improvement of this little piece
 * of code.
 * 
 * For usage instructions please visit http://fromvega.com/scripts
 */

(function($) {

	// to track if the mouse button is pressed
	var isMouseDown = false;

	// to track the current element being dragged
	var currentElement = null;

	// callback holders
	var dropCallbacks = {};
	var dragCallbacks = {};

	// bubbling status
	var bubblings = {};

	// global position records
	var lastMouseX;
	var lastMouseY;
	var lastElemTop;
	var lastElemLeft;

	// track element dragStatus
	var dragStatus = {};

	// 用户允许圈定的范围
	var flag = false;// 是否指定
	var leftupX = 0;
	var leftupY = 0;
	var rightdownX = 0;
	var rightdownY = 0;

	// if user is holding any handle or not
	var holdingHandler = false;

	// returns the mouse (cursor) current position
	$.getMousePosition = function(e) {
		var posx = 0;
		var posy = 0;

		if (!e)
			var e = window.event;

		if (e.pageX || e.pageY) {
			posx = e.pageX;
			posy = e.pageY;
		} else if (e.clientX || e.clientY) {
			posx = e.clientX + document.body.scrollLeft
					+ document.documentElement.scrollLeft;
			posy = e.clientY + document.body.scrollTop
					+ document.documentElement.scrollTop;
		}

		return {
			'x' : posx,
			'y' : posy
		};
	};

	// updates the position of the current element being dragged
	$.updatePosition = function(e) {
		var pos = $.getMousePosition(e);

		var spanX = (pos.x - lastMouseX);
		var spanY = (pos.y - lastMouseY);

		// 指定图片左上角的绝对坐标
		var lastTop = lastElemTop + spanY;
		var lastLeft = lastElemLeft + spanX;
		// 图片右下角
		var lastRightDownX = lastLeft + $(currentElement).width();
		var lastRightDownY = lastTop + $(currentElement).height();
		if (flag == true) {
			// 图片超过左上角
			if (lastTop < leftupY) {
				lastTop = leftupY;
			}
			if (lastLeft < leftupX) {
				lastLeft = leftupX;
			}
			// 图片超过右下角
			if (rightdownX < lastRightDownX) {
				lastLeft = rightdownX - $(currentElement).width();
			}

			if (rightdownY < lastRightDownY) {
				lastTop = rightdownY - $(currentElement).height();
			}
		}

		$(currentElement).css("top", lastTop);
		$(currentElement).css("left", lastLeft);
	};

	// when the mouse is moved while the mouse button is pressed
	$(document).mousemove(function(e) {
		if (isMouseDown && dragStatus[currentElement.id] != 'false') {
			// update the position and call the registered function
			$.updatePosition(e);
			if (dragCallbacks[currentElement.id] != undefined) {
				dragCallbacks[currentElement.id](e, currentElement);
			}

			return false;
		}
	});

	// when the mouse button is released
	$(document).mouseup(function(e) {
		if (isMouseDown && dragStatus[currentElement.id] != 'false') {
			isMouseDown = false;
			$(currentElement).fadeTo("fast", 1);
			if (dropCallbacks[currentElement.id] != undefined) {
				dropCallbacks[currentElement.id](e, currentElement);
			}
	
			return false;
		}
	});

	// register the function to be called while an element is being dragged
	$.fn.ondrag = function(callback) {
		return this.each(function() {
			dragCallbacks[this.id] = callback;
		});
	};

	// register the function to be called when an element is dropped
	$.fn.ondrop = function(callback) {
		return this.each(function() {
			dropCallbacks[this.id] = callback;
		});
	};

	// disable the dragging feature for the element
	$.fn.dragOff = function() {
		return this.each(function() {
			dragStatus[this.id] = 'off';
		});
	};

	// enable the dragging feature for the element
	$.fn.dragOn = function() {
		return this.each(function() {
			dragStatus[this.id] = 'on';
		});
	};

	// set a child element as a handler
	$.fn.setHandler = function(handlerId) {
		return this.each(function() {
			var draggable = this;

			// enable event bubbling so the user can reach the handle
			bubblings[this.id] = true;

			// reset cursor style
			$(draggable).css("cursor", "");

			// set current drag status
			dragStatus[draggable.id] = "handler";

			// change handle cursor type
			$("#" + handlerId).css("cursor", "move");

			// bind event handler
			$("#" + handlerId).mousedown(function(e) {
				holdingHandler = true;
				$(draggable).trigger('mousedown', e);
			});

			// bind event handler
			$("#" + handlerId).mouseup(function(e) {
				holdingHandler = false;
			});
		});
	};

	/**
	 * 限定拖动的区域
	 */
	$.fn.area = function(flg, str) {
		flag = flg;
		// 不指定拖动区域
		if (flag == false) {
			return;
		}

		var obj = $(str);
		// 获取对象元素的位置
		var offset = obj.offset();
		// 获取对象元素的宽度
		leftupX = offset.left;
		leftupY = offset.top;
		rightdownX = leftupX + obj.width();
		rightdownY = leftupY + obj.height();

		// test
		// $("#show").html(leftupX+" "+leftupY+" "+rightdownX+" "+rightdownY);
	};
	

	// set an element as draggable - allowBubbling enables/disables event
	// bubbling
	// allowBubbling, handle_ids){
	$.fn.easydrag = function(allowBubbling, handle_ids) {

		return this.each(function() {

			// if no id is defined assign a unique one
			if (undefined == this.id)
				this.id = 'easydrag' + time();

			if (handle_ids) {
				for ( var i = 0; i < handle_ids.length; i++) {
					$("#" + handle_ids[i]).css("cursor", "move");
				}
			} else {
				$(this).css("cursor", "move");
			}
			
			// when an element receives a mouse press
			$(this).mousedown(function(e) {
				if (handle_ids) {
					// 鍒ゆ柇鏄惁鏄湪鎷栧姩鏌愪釜 handle
					var srcElement;
					if (e)
						srcElement = e.srcElement;
					else
						srcElement = window.event.srcElement;

					var exists = false;
					if (srcElement.id != undefined) {
						for ( var i = 0; i < handle_ids.length; i++) {
							if (handle_ids[i] == srcElement.id) {
								exists = true;
								break;
							}
						}
					}
					if (!exists)
						return false;
				}
				// set it as absolute positioned
				$(this).css("position", "absolute");

				// set z-index
				$(this).css("z-index", "10000");

				// update track variables
				isMouseDown = true;
				currentElement = this;

				// retrieve positioning properties
				var pos = $.getMousePosition(e);
				lastMouseX = pos.x;
				lastMouseY = pos.y;

				lastElemTop = this.offsetTop;
				lastElemLeft = this.offsetLeft;

				$.updatePosition(e);

				//$(this).css("cursor", "text");
				
				return allowBubbling ? true : false;
			});
		});

	};

})(jQuery);